package com.fandou.airobot.database;

import android.os.Parcel;
import android.os.Parcelable;
import android.util.SparseBooleanArray;

import androidx.annotation.IntDef;
import androidx.annotation.Keep;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.room.Entity;
import androidx.room.Ignore;
import androidx.room.PrimaryKey;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * @author Jm
 * @date 2020/6/2412:00
 * @description
 */
@Keep
@Entity
public class Alarm implements Parcelable {

    @PrimaryKey(autoGenerate = true)
    public long id;

    /**
     * 闹钟类型
     * {@link AlarmConstants.AlarmType}
     */
    public int alarmType;

    /**
     * 提醒通知类型
     * 0 铃声
     * 1 震动
     * 3 无铃声，无震动，只有提示框提醒
     * {@link AlarmConstants.RemindType}
     */
    public int alertType;

    /**
     * 闹钟周期(预留field)
     * 0 仅一次
     * 1 每天
     * 2 间隔一周
     * {@link AlarmConstants.Period}
     */
    public int alarmPeriod;

    /**
     * 备注
     */
    @Nullable
    public String remark;

    /**
     * 时
     */
    public int hour;

    /**
     * 分
     */
    public int minute;

    /**
     * 秒
     */
    public int second;

    /**
     * 闹钟的时间戳
     */
    public long time;

    /**
     * 倒计时时间戳
     */
    public long countdownTimestamp;


    /**
     * 闹钟或者倒计时是否启用
     */
    @NonNull
    public Boolean enable;

    /**
     * 是否每天重复
     */
    @NonNull
    public Boolean repeat;

    @Ignore
    private SparseBooleanArray allDays;

    public Alarm(long time, @Nullable String remark, int hour, int minute, boolean repeat) {
        this.alarmType = AlarmConstants.AlarmType.ALARM;
        this.time = time;
        this.remark = remark;
        this.enable = true;
        this.repeat = repeat;
        this.hour = hour;
        this.minute = minute;
        this.alertType = AlarmConstants.RemindType.ALERT_SOUND;
        setAllDays(buildDaysArray(MON
                , TUES
                , WED
                , THURS
                , FRI
                , SAT
                , SUN
        ));
//        if (repeat) {
//            setAllDays(buildDaysArray(MON
//                    , TUES
//                    , WED
//                    , THURS
//                    , FRI
//                    , SAT
//                    , SUN
//            ));
//        } else {
//            setAllDays(buildDaysArray(TUES
//            ));
//        }
    }


    @NonNull
    public Boolean getRepeat() {
        return repeat;
    }

    public void setRepeat(@NonNull Boolean repeat) {
        this.repeat = repeat;
    }

    public SparseBooleanArray getAllDays() {
        return allDays;
    }

    public boolean getDay(@Days int day) {
        return allDays.get(day);
    }

    public void setDay(@Days int day, boolean isAlarmed) {
        allDays.append(day, isAlarmed);
    }


    public void setAllDays(SparseBooleanArray allDays) {
        this.allDays = allDays;
    }

    public static final int MON = 1;
    public static final int TUES = 2;
    public static final int WED = 3;
    public static final int THURS = 4;
    public static final int FRI = 5;
    public static final int SAT = 6;
    public static final int SUN = 7;

    @Retention(RetentionPolicy.SOURCE)
    @IntDef({MON, TUES, WED, THURS, FRI, SAT, SUN})
    @interface Days {
    }

    public static SparseBooleanArray buildDaysArray(@Days int... days) {

        final SparseBooleanArray array = buildBaseDaysArray();

        for (@Days int day : days) {
            array.append(day, true);
        }

        return array;

    }

    private static SparseBooleanArray buildBaseDaysArray() {

        final int numDays = 7;

        final SparseBooleanArray array = new SparseBooleanArray(numDays);

        array.put(MON, true);
        array.put(TUES, true);
        array.put(WED, true);
        array.put(THURS, true);
        array.put(FRI, true);
        array.put(SAT, true);
        array.put(SUN, true);

        return array;

    }

    @Ignore
    public Alarm(int alarmType, int alertType, int alarmPeriod, @Nullable String remark, int hour, int minute, int second, long countdownTimestamp, @NonNull Boolean enable) {
        this.alarmType = alarmType;
        this.alertType = alertType;
        this.alarmPeriod = alarmPeriod;
        this.remark = remark;
        this.hour = hour;
        this.minute = minute;
        this.second = second;
        this.countdownTimestamp = countdownTimestamp;
        this.enable = enable;
    }

    public long getTime() {
        return time;
    }

    public void setTime(long time) {
        this.time = time;
    }


    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public int getSecond() {
        return second;
    }

    public void setSecond(int second) {
        this.second = second;
    }

    public int getAlarmType() {
        return alarmType;
    }

    public void setAlarmType(int alarmType) {
        this.alarmType = alarmType;
    }

    public int getAlertType() {
        return alertType;
    }

    public void setAlertType(int alertType) {
        this.alertType = alertType;
    }

    public int getAlarmPeriod() {
        return alarmPeriod;
    }

    public void setAlarmPeriod(int alarmPeriod) {
        this.alarmPeriod = alarmPeriod;
    }

    @Nullable
    public String getRemark() {
        return remark;
    }

    public void setRemark(@Nullable String remark) {
        this.remark = remark;
    }

    public int getHour() {
        return hour;
    }

    public void setHour(int hour) {
        this.hour = hour;
    }

    public int getMinute() {
        return minute;
    }

    public void setMinute(int minute) {
        this.minute = minute;
    }

    public long getCountdownTimestamp() {
        return countdownTimestamp;
    }

    public void setCountdownTimestamp(long countdownTimestamp) {
        this.countdownTimestamp = countdownTimestamp;
    }

    @NonNull
    public Boolean getEnable() {
        return enable;
    }

    public void setEnable(@NonNull Boolean enable) {
        this.enable = enable;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeLong(this.id);
        dest.writeInt(this.alarmType);
        dest.writeInt(this.alertType);
        dest.writeInt(this.alarmPeriod);
        dest.writeString(this.remark);
        dest.writeInt(this.hour);
        dest.writeInt(this.minute);
        dest.writeInt(this.second);
        dest.writeLong(this.time);
        dest.writeLong(this.countdownTimestamp);
        dest.writeValue(this.enable);
        dest.writeValue(this.repeat);
        dest.writeSparseBooleanArray(this.allDays);
    }

    protected Alarm(Parcel in) {
        this.id = in.readLong();
        this.alarmType = in.readInt();
        this.alertType = in.readInt();
        this.alarmPeriod = in.readInt();
        this.remark = in.readString();
        this.hour = in.readInt();
        this.minute = in.readInt();
        this.second = in.readInt();
        this.time = in.readLong();
        this.countdownTimestamp = in.readLong();
        this.enable = (Boolean) in.readValue(Boolean.class.getClassLoader());
        this.repeat = (Boolean) in.readValue(Boolean.class.getClassLoader());
        this.allDays = in.readSparseBooleanArray();
    }

    public static final Creator<Alarm> CREATOR = new Creator<Alarm>() {
        @Override
        public Alarm createFromParcel(Parcel source) {
            return new Alarm(source);
        }

        @Override
        public Alarm[] newArray(int size) {
            return new Alarm[size];
        }
    };
}
